package evtop

import (
	"github.com/pkg/errors"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/interactiond"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/ddd"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/log"
)

func newInteractionListener(d ddd.Domain) *intListener {
	return &intListener{
		base: base{
			d: d,
		},
		igar: d.SubDomain(interactiond.DomainID).AggregateRootByID(interactiond.Group).(interactiond.GroupAggregateRoot),
		rar:  d.SubDomain(interactiond.DomainID).AggregateRootByID(interactiond.Replay).(interactiond.ReplayAggregateRoot),
		iiar: d.SubDomain(interactiond.DomainID).AggregateRootByID(interactiond.Interaction).(interactiond.InteractionAggregateRoot),
		tar:  d.SubDomain(interactiond.DomainID).AggregateRootByID(interactiond.Type).(interactiond.TypeAggregateRoot),
	}
}

type intListener struct {
	base
	rar  interactiond.ReplayAggregateRoot
	iiar interactiond.InteractionAggregateRoot
	tar  interactiond.TypeAggregateRoot

	igar interactiond.GroupAggregateRoot
}

func (l intListener) onReplay() ddd.EventListener {
	return l.creEventListener(func(ctx ddd.Context, evt ddd.Event) error {
		log.Debugf("执行事件监听:intListener onReplay :%#v", evt)
		replay, ok := evt.Data.(*interactiond.ReplayAggregate)
		if !ok {
			return errors.Errorf("获取事件数据格式错误：%#v", evt.Data)

		}

		l.igar.AddReplayNum(ctx, replay.IGID, interactiond.ChildReplyTotal{
			LastTime:     replay.CreTime,
			LastReplayer: replay.Creator,
			ReplayNum:    1,
		})

		for replay.ParentID != "" {
			// 需要修改评论的子评论数
			preplay, err := l.rar.GetReplay(ctx, replay.ParentID)
			if err != nil {
				return errors.Wrapf(err, "获取上级评论失败：%v", err)

			}
			preplay.AddReplayNum(ctx, 1)
			replay = preplay
		}

		return nil
	})
}
func (l intListener) onInteractionAdd() ddd.EventListener {
	return l.creEventListener(func(ctx ddd.Context, evt ddd.Event) error {
		log.Debugf("执行事件监听:intListener onInteractionAdd :%#v", evt)
		iiid, ok := evt.Data.(string)
		if !ok {
			return errors.Errorf("获取事件数据格式错误：%#v", evt.Data)

		}
		i, err := l.iiar.GetInteraction(ctx, iiid)
		if err != nil {
			return err
		}
		g, err := l.igar.GetGroup(ctx, i.IGID)
		if err != nil {
			return err
		}
		// t, err := l.tar.GetType(ctx, i.Code)
		// if err != nil {
		// 	return err
		// }
		err = g.AddIntsNum(ctx, i.Code, i.Value)
		if err != nil {
			return err
		}

		if g.TargetType == interactiond.IGTTReplay {
			r, err := l.rar.GetReplay(ctx, g.TargetID)
			if err != nil {
				return err
			}
			return r.AddLikeNum(ctx, 1)
		}
		return nil
	})
}
func (l intListener) onInteractionDelete() ddd.EventListener {
	return l.creEventListener(func(ctx ddd.Context, evt ddd.Event) error {
		log.Debugf("执行事件监听:intListener onInteractionDelete :%#v", evt)
		i, ok := evt.Data.(*interactiond.InteractionAggregate)
		if !ok {
			return errors.Errorf("获取事件数据格式错误：%#v", evt.Data)
		}
		g, err := l.igar.GetGroup(ctx, i.IGID)
		if err != nil {
			return err
		}
		err = g.SubIntsNum(ctx, i.Code, i.Value)
		if err != nil {
			return err
		}

		if g.TargetType == interactiond.IGTTReplay {
			r, err := l.rar.GetReplay(ctx, g.TargetID)
			if err != nil {
				return err
			}
			return r.AddLikeNum(ctx, -1)
		}
		return nil
	})
}
func (l intListener) onInteractionUpdateValue() ddd.EventListener {
	return l.creEventListener(func(ctx ddd.Context, evt ddd.Event) error {
		log.Debugf("执行事件监听:intListener onInteractionUpdateValue :%#v", evt)

		d, ok := evt.Data.(map[string]interface{})
		if !ok {
			return errors.Errorf("获取事件数据格式错误：%#v", evt.Data)

		}
		var old *interactiond.InteractionAggregate
		var new *interactiond.InteractionAggregate

		if tmpn, ok := d["new"]; ok && tmpn != nil {
			if new, ok = tmpn.(*interactiond.InteractionAggregate); !ok {
				return errors.Errorf("获取事件数据格式错误,new格式错误")
			}
		}
		if tmpn, ok := d["old"]; ok && tmpn != nil {
			if old, ok = tmpn.(*interactiond.InteractionAggregate); !ok {
				return errors.Errorf("获取事件数据格式错误,old格式错误")
			}
		}
		if old == nil || new == nil {
			return errors.Errorf("获取事件数据格式错误")
		}

		g, err := l.igar.GetGroup(ctx, old.IGID)
		if err != nil {
			return err
		}

		return g.UpdateIntsNum(ctx, old.Code, old.Value, new.Value)

	})
}
